import 'dart:convert';

import 'package:lib_core/gt_message_channel_api.dart';
import 'package:lib_core/logger/gt_logger.dart';
import 'package:lib_core/model/lib_core_event_model.dart';

/// Author: Shper
/// Created: 2023/7/9

typedef GTMessageCenterCallback = void Function(String actionType, String actionName, Map<String, dynamic>? data);

class GTMessageCenter {

  GTMessageCenter._();

  static final GTMessageCenter _instance = GTMessageCenter._();

  static GTMessageCenter get instance => _instance;

  /// 交互通道 初始化
  final _messageChannel = GTMessageChannelFlutterImpl._();

  final _hostApi = GTMessageChannelHostApi();

  static final Map<String, List<GTMessageCenterCallback?>>  _listenerMap = {};

  /// 增加监听具体分类的通知
  static addListener(Enum action, GTMessageCenterCallback callback) {
    var actionKey = _generateActionKeyByEnum(action);

    var callbackList = _listenerMap[actionKey] ??= [];
    callbackList.add(callback);
    // 清除空数据
    // callbackList.removeWhere((element) => element == null);
    _listenerMap[actionKey] = callbackList;
    GTLogger.debug("GTMessageChannel addListener - actionKey: $actionKey, listener: ${callbackList.length}");
  }

  /// 增加 监听全部分类的通知
  static addListenerByList(List<Enum> actions, GTMessageCenterCallback callback) {
    for (var action in actions) {
      addListener(action, callback);
    }
  }

  /// 清除 监听器
  static removeListener(Enum action, GTMessageCenterCallback callback) {
    var actionKey = _generateActionKeyByEnum(action);

    var callbackList = _listenerMap[actionKey];
    callbackList?.removeWhere((element) => element == callback);
    // 清理空数据
    callbackList?.removeWhere((element) => element == null);
  }

  /// 清除 监听器
  static removeListenerByList(List<Enum> actions, GTMessageCenterCallback callback) {
    for (var action in actions) {
      removeListener(action, callback);
    }
  }

  /// 发送消息
  static sendMessageJson(Enum action, String messagesJson) {
    GTLogger.debug("GTMessageChannel sendMessage - actionType: ${action.runtimeType}, actionName:${action.name}, messages: $messagesJson");
    _instance._hostApi.handleMessage('${action.runtimeType}', action.name , messagesJson);
  }

  static sendMessage(Enum action, Map<String, dynamic> messages) {
    GTLogger.debug("GTMessageChannel sendMessage - actionType: ${action.runtimeType}, actionName:${action.name}, messages: $messages");
    var messagesJson = json.encode(messages);
    _instance._hostApi.handleMessage('${action.runtimeType}', action.name , messagesJson);
  }

  // 分发消息
  static _dispatchMassage(GTLiCoreEventModel messageModel) {
    var actionKey = _generateActionKey(messageModel.actionType, messageModel.actionName);
    // 先分发具体消息
    var callbackList = _listenerMap[actionKey] ??= [];
    GTLogger.debug("GTMessageChannel dispatchListens action: $actionKey; callbackList: ${callbackList.length}");

    for (var element in callbackList) {
      try {
        element?.call(messageModel.actionType, messageModel.actionName, messageModel.data);
      } catch (e) {
        GTLogger.error(e);
      }
    }
    // 清除空数据
    callbackList.removeWhere((element) => element == null);
  }

  /// 根据 枚举生成 action key
  static String _generateActionKeyByEnum(Enum action) {
    return "${action.runtimeType}.${action.name}";
  }

  /// 根据 枚举生成 action key
  static String _generateActionKey(String actionType, String actionName) {
    return "$actionType.$actionName";
  }

}

class GTMessageChannelFlutterImpl extends GTMessageChannelFlutterApi {

  GTMessageChannelFlutterImpl._() {
    GTLogger.debug("GTMessageChannel setup");
    GTMessageChannelFlutterApi.setup(this);
  }

  // 接受 原生侧消息
  @override
  void handleMessage(String actionType, String actionName, String messageJson) {
    GTLogger.debug("GTMessageChannel handleMessage - actionType: $actionType, actionName:$actionName, messageJson: $messageJson");

    // 解析数据
    var messageModel = GTLiCoreEventModel();
    messageModel.actionType = actionType;
    messageModel.actionName = actionName;
    messageModel.data = json.decode(messageJson);
    if (messageModel.isInvalid()) {
      GTLogger.debug("GTMessageChannel: The Event message is invalid.");
      return;
    }

    // 合格消息进行分发消息
    GTMessageCenter._dispatchMassage(messageModel);
  }
}